package com.tencent.examples.blueking.mongo.service;

import com.mongodb.BasicDBObject;
import com.tencent.bk.utils.blueking.tools.CommonSugar;
import com.tencent.bk.utils.blueking.tools.StringConverters;
import com.tencent.examples.blueking.mongo.extend.biz.CrudBiz;
import com.tencent.examples.blueking.extend.QueryParam;
import com.tencent.examples.blueking.mongo.model.ObjectBase;
import com.tencent.examples.blueking.mongo.repository.ObjectBaseRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Service("ObjectBaseService")
public class ObjectBaseService extends CrudBiz<ObjectBaseRepository> {

    @Resource
    private MongoTemplate mongoTemplate;

    public List<ObjectBase> getQyInfo(String bk_obj_id) {
        List<ObjectBase> objectBaseList = dao.findObjectBaseByBk_obj_id(bk_obj_id);
        return objectBaseList;
    }

    public Long findAA(Map<String, String> map) {
        return this.getTotal(map);
    }

    public Long getTotal(Map<String, String> map) {
        Query query = new Query();
        String bk_obj_id = map.get("bk_obj_id");
        if (StringUtils.isNotBlank(bk_obj_id)) {
            query.addCriteria(Criteria.where("bk_obj_id").is(map.get("bk_obj_id")));
        }
        //店铺状态
        String store_status = map.get("store_status");
        if (StringUtils.isNotBlank(store_status)) {
            query.addCriteria(Criteria.where("store_status").is(store_status));
        }

//        String regionname = map.get("regionname");
//        if (StringUtils.isNotBlank(regionname)) {
//            query.addCriteria(Criteria.where("regionname").is(regionname));
//        }
        //是否监控
        String store_monitor = map.get("store_monitor");
        if (StringUtils.isNotBlank(store_monitor)) {
            query.addCriteria(Criteria.where("store_monitor").is(store_monitor));
        }
        //门店类型
        String store_type = map.get("store_type");
        if (StringUtils.isNotBlank(store_type)) {
            query.addCriteria(Criteria.where("store_type").is(store_type));
        }

        //新店总数
//        String store_type=map.get("store_type");
//        if (StringUtils.isNotBlank(store_type)){
//            query.addCriteria(Criteria.where("store_type").is(store_type));
//        }

        //断电总数
        String spower_status = map.get("spower_status");
        if (StringUtils.isNotBlank(spower_status)) {
            query.addCriteria(Criteria.where("spower_status").is(spower_status));
        }

        //断网总数
        String snet_status = map.get("snet_status");
        if (StringUtils.isNotBlank(snet_status)) {
            query.addCriteria(Criteria.where("snet_status").is(snet_status));
        }
        //装修状态
        String renovation_type = map.get("renovation_type");
        if (StringUtils.isNotBlank(renovation_type)) {
            query.addCriteria(Criteria.where("renovation_type").is(renovation_type));
        }
        //闭店门店状态
        String sclose_status = map.get("sclose_status");
        if (StringUtils.isNotBlank(sclose_status)) {
            query.addCriteria(Criteria.where("sclose_status").is(sclose_status));
        }
        //门店内网线路类型
        String netinter_isp = map.get("netinter_isp");
        if (StringUtils.isNotBlank(netinter_isp)) {
            query.addCriteria(Criteria.where("netinter_isp").is(netinter_isp));
        }
        //门店内网运营商类型
        String netinter_isp_type = map.get("netinter_isp_type");
        if (StringUtils.isNotBlank(netinter_isp_type)) {
            query.addCriteria(Criteria.where("netinter_isp_type").is(netinter_isp_type));
        }

        //计算门店状态
        String ops_status = map.get("ops_status");
        if (StringUtils.isNotBlank(ops_status)) {
            query.addCriteria(Criteria.where("ops_status").is(ops_status));
        }
        //店铺区域
        String region_en = map.get("region_en");
        if (StringUtils.isNotBlank(region_en)) {
            query.addCriteria(Criteria.where("region_en").is(region_en));
        }

        Long to = mongoTemplate.count(query, ObjectBase.class);
        return to;
    }


    /**
     * 分页查询
     *
     * @param queryParam
     * @return
     */
    public List<ObjectBase> searchAll(QueryParam queryParam) {
        Query query = new Query();
        query.with(new Sort(new Sort.Order(CommonSugar.getTypedDefault(queryParam.getSort(), Sort.Direction.DESC), CommonSugar.getTypedDefault(queryParam.getSortby(), "id"))));
        Map<String, String> dataMap = queryParam.getSqlMap();
        String bk_obj_id = dataMap.get("bk_obj_id");
        if (StringUtils.isNotEmpty(bk_obj_id)) {
            query.addCriteria(Criteria.where("bk_obj_id").is(bk_obj_id));
        }
        String store_status = dataMap.get("store_status");
        if (StringUtils.isNotEmpty(store_status)) {
            query.addCriteria(Criteria.where("store_status").is(store_status));
        }
        String bk_inst_id = dataMap.get("bk_inst_id");
        if (StringUtils.isNotEmpty(bk_inst_id)) {
            query.addCriteria(Criteria.where("bk_inst_id").is(StringConverters.ToInteger(bk_inst_id)));
        }
        //计划开店小于等于筛选时间
        String plan_store_open_date_lte = dataMap.get("plan_store_open_date_lte");
        if (StringUtils.isNotEmpty(plan_store_open_date_lte)) {
            query.addCriteria(Criteria.where("plan_store_open_date").lte(plan_store_open_date_lte));
        }
        //计划开店大于等于筛选时间
        String plan_store_open_date_gte = dataMap.get("plan_store_open_date_gte");
        if (StringUtils.isNotEmpty(plan_store_open_date_gte)) {
            query.addCriteria(Criteria.where("plan_store_open_date").gte(plan_store_open_date_gte));
        }
        //实际开店小于等于筛选时间
        String store_open_date_lte = dataMap.get("store_open_date_lte");
        if (StringUtils.isNotEmpty(store_open_date_lte)) {
            query.addCriteria(Criteria.where("store_open_date").lte(store_open_date_lte));
        }
        //实际开店大于等于筛选时间
        String store_open_date_gte = dataMap.get("store_open_date_gte");
        if (StringUtils.isNotEmpty(store_open_date_gte)) {
            query.addCriteria(Criteria.where("store_open_date").gte(store_open_date_gte));
        }
        String global_id = dataMap.get("global_id");
        if (StringUtils.isNotEmpty(global_id)) {
            query.addCriteria(Criteria.where("global_id").is(global_id));
        }
        String weekStart = dataMap.get("weekStart");
        if (StringUtils.isNotEmpty(weekStart)) {
            Integer day_of_week_start = StringConverters.ToInteger(weekStart);
            String key = "store_" + day_of_week_start + "start_time";
            query.addCriteria(Criteria.where(key).exists(true));
        }
        String weekClose = dataMap.get("weekClose");
        if (StringUtils.isNotEmpty(weekClose)) {
            Integer day_of_week_close = StringConverters.ToInteger(weekClose);
            String key = "store_" + day_of_week_close + "close_time";
            query.addCriteria(Criteria.where(key).exists(true));
        }
        String storecode = dataMap.get("storecode");
        if (StringUtils.isNotEmpty(storecode)) {
            query.addCriteria(Criteria.where("storecode").is(storecode));
        }
        QueryParam.pagination(query, queryParam);//分页设置
        return mongoTemplate.find(query, ObjectBase.class);
    }

    /**
     * 原生多表查询
     *
     * @param queryParam
     * @return
     */
    public List<BasicDBObject> getAggregation(QueryParam queryParam, Pageable pageable) {
        Map<String, String> dataMap = queryParam.getSqlMap();
        LookupOperation lookupAgg_hostBase = Aggregation.lookup("cc_HostBase", "bk_classification_id", "bk_host_id", "objDes");
        Criteria criteria = new Criteria();
        String bk_classification_name = dataMap.get("bk_classification_name");
        if (StringUtils.isNotEmpty(bk_classification_name)) {
            criteria.and("bk_classification_name").is(bk_classification_name);
        }
        String bk_obj_name = dataMap.get("bk_obj_name");
        if (StringUtils.isNotEmpty(bk_obj_name)) {
            criteria.and("objDes.bk_obj_name").is(bk_obj_name);
        }
        String bk_obj_id = dataMap.get("bk_obj_id");
        if (StringUtils.isNotEmpty(bk_obj_id)) {
            criteria.and("bk_obj_id").is(bk_obj_id);
        }
        String bk_inst_id = dataMap.get("bk_inst_id");
        if (StringUtils.isNotEmpty(bk_inst_id)) {
            criteria.and("bk_inst_id").is(StringConverters.ToInteger(bk_inst_id));
        }
        MatchOperation matchOperation = Aggregation.match(criteria);//lookupAgg一定要在matchOperation的前面 两者顺序颠倒就过滤不了
        Aggregation aggregation = Aggregation.newAggregation(lookupAgg_hostBase, matchOperation,
                Aggregation.sort(pageable.getSort()),//排序字段
                //分页操作，pageNumber为当前页数，pageSize为每页显示条数
                Aggregation.skip(pageable.getPageNumber() > 1 ? (pageable.getPageNumber() - 1) * pageable.getPageSize() : 0),
                Aggregation.limit(pageable.getPageSize()));
        AggregationResults<BasicDBObject> ret = mongoTemplate.aggregate(aggregation, "cc_ObjectBase", BasicDBObject.class);
        return ret.getMappedResults();
    }

    /**
     * 原生多表查询--不带分页
     *
     * @param queryParam
     * @return
     */
    public List<BasicDBObject> getAggregation(QueryParam queryParam) {
        Map<String, String> dataMap = queryParam.getSqlMap();
        Criteria criteria = new Criteria();
        String bk_obj_id = dataMap.get("bk_obj_id");
        if (StringUtils.isNotEmpty(bk_obj_id)) {
            criteria.and("bk_obj_id").is(bk_obj_id);
        }
        MatchOperation matchOperation = Aggregation.match(criteria);//lookupAgg一定要在matchOperation的前面 两者顺序颠倒就过滤不了
        Aggregation aggregation = Aggregation.newAggregation(matchOperation);
        AggregationResults<BasicDBObject> ret = mongoTemplate.aggregate(aggregation, "cc_ObjectBase", BasicDBObject.class);
        return ret.getMappedResults();
    }

    /**
     * 原生多表查询（多对一）
     *
     * @param queryParam
     * @return
     */
    public List<BasicDBObject> getAggregation1(QueryParam queryParam) {
        Map<String, String> dataMap = queryParam.getSqlMap();
        Criteria criteria = new Criteria();
        String bk_obj_id = dataMap.get("bk_obj_id");
        if (StringUtils.isNotEmpty(bk_obj_id)) {
            criteria.and("bk_obj_id").is(bk_obj_id);
        }
        criteria.and("province").exists(true).ne(null).ne("");
        String open_startDate = dataMap.get("open_startDate");
        String open_endDate = dataMap.get("open_endDate");
        if (StringUtils.isNotEmpty(open_startDate) && StringUtils.isNotEmpty(open_endDate)) {
            criteria.and("store_open_date").gte(open_startDate).lte(open_endDate).exists(true).ne(null).ne("");
        }

        String plan_startDate = dataMap.get("plan_startDate");
        String plan_endDate = dataMap.get("plan_endDate");
        if (StringUtils.isNotEmpty(plan_startDate) && StringUtils.isNotEmpty(plan_endDate)) {
            criteria.and("plan_store_open_date").gte(plan_startDate).lte(plan_endDate).exists(true).ne(null).ne("");
        }
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),//查询条件
                Aggregation.project("province"),
                Aggregation.unwind("province"),
                Aggregation.group("province").count().as("count"),
                Aggregation.project("count").and("province").previousOperation(),
                Aggregation.sort(Sort.Direction.DESC, "count")
        );
        AggregationResults<BasicDBObject> ret = mongoTemplate.aggregate(aggregation, "cc_ObjectBase", BasicDBObject.class);
        return ret.getMappedResults();
    }
}
